<?php
/**
 * Created by PhpStorm.
 * User: zhangrxiang
 * Date: 2016/9/13
 * Time: 16:12
 */

function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
	global $wp_filter, $merged_filters;
	# 用于声明全局变量$wp_filter和$merged_filters；
	$idx = _wp_filter_build_unique_id($tag, $function_to_add, $priority);
	# 声明变量$idx并赋值，其值为调用_wp_filter_build_unique_id()函数所得唯一值，关于该函数的源码分析可见下文；
	$wp_filter[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
	# 为关联数组$wp_filter[$tag][$priority][$idx]赋值，其值为一个关联数组，该数组有两个值，一个为挂载函数名，另一个为该函数接收的参数个数；
	unset( $merged_filters[ $tag ] );
	# 标记该钩子上新增了函数，更改$wp_filter数组状态，具体作用见apply_filters()函数$merged_filters部分源码说明；
	return true;
}

function _wp_filter_build_unique_id($tag, $function, $priority) {
	global $wp_filter;
	# 声明全局变量$wp_filter；
	static $filter_id_count = 0;
	# 声明静态变量$filter_id_count并赋初值为0；
	if ( is_string($function) )
		return $function;
	# 如果$function的值是字符串则返回该字符串；
	if ( is_object($function) ) {
		$function = array( $function, '' );
	} else {
		$function = (array) $function;
	}
	# 如果$function是一个对象则将其放入数组，否则将其强制转换为数组；
	if (is_object($function[0])) {
		if ( function_exists('spl_object_hash') ) {
			return spl_object_hash($function[0]) . $function[1];
		} else {
			$obj_idx = get_class($function[0]).$function[1];
			if ( !isset($function[0]->wp_filter_id) ) {
				if ( false === $priority )
					return false;
				$obj_idx .= isset($wp_filter[$tag][$priority]) ? count((array)$wp_filter[$tag][$priority]) : $filter_id_count;
				$function[0]->wp_filter_id = $filter_id_count;
				++$filter_id_count;
			} else {
				$obj_idx .= $function[0]->wp_filter_id;
			}
			return $obj_idx;
		}
		# 如果spl_object_hash()函数存在则根据该函数返回一个唯一哈希值，否则使用其他方法返回一个唯一值；
	} else if ( is_string($function[0]) ) {
		return $function[0].$function[1];
	}
	# 如果$function[0]是字符串则返回该字符串
}